package com.pe.pgn.clubpgn.dao.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.pe.pgn.clubpgn.common.CLPConstantes;
import com.pe.pgn.clubpgn.dao.ReporteLiquidacionDao;
import com.pe.pgn.clubpgn.dao.hibernate.GenericDaoHibernate;
import com.pe.pgn.clubpgn.domain.ClpbClientePersona;
import com.pe.pgn.clubpgn.domain.ClpbPrograma;
import com.pe.pgn.clubpgn.domain.ClpdMeta;
import com.pe.pgn.clubpgn.domain.ClpmHistorialLiquidacion;
import com.pe.pgn.clubpgn.domain.ClpmLiquidacion;
import com.pe.pgn.clubpgn.domain.ClprPeriodoLiquidacion;
import com.pe.pgn.clubpgn.domain.ClprPeriodoPrograma;
import com.pe.pgn.clubpgn.domain.beans.BNPeriodo;
import com.pe.pgn.clubpgn.domain.beans.BNReporteLiquidacion;
import com.pe.pgn.clubpgn.domain.beans.BNResumenLiquidacion;
import com.pe.pgn.clubpgn.webapp.util.CalendarUtil;

/**
 * @author Edwin Farfan
 * 
 * Modify by @author ingas
 * 			Add method obtenerRegistrosLiquidacionPorPeriodo
 * 	
 * Modify by @author frank.ayala
 * 			Add method verificarExistePeriodoLiq
 * 	
 */


@SuppressWarnings("unchecked")
@Repository("reporteLiquidacionDao")
public class ReporteLiquidacionDaoImpl extends GenericDaoHibernate<BNReporteLiquidacion, Long> implements ReporteLiquidacionDao {

	public ReporteLiquidacionDaoImpl() {
		super(BNReporteLiquidacion.class);
	}

	private JdbcTemplate jdbcTemplate;
	
	@Autowired
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}

	public List<Map<String, Object>> listaReporteLiquidacion() {
		
		StringBuffer query= new StringBuffer();
		
		query.append("select cliente.id as id, (cliente.de_nombre ||' '|| cliente.de_ape_paterno ||' '|| cliente.de_ape_materno) nombre, ");
		query.append(" cliente.co_code_numero_documento documento, ");
		query.append(" cliente.de_direccion direccion, ");
		query.append("cliente.co_telefono_fijo telefono, ");
		query.append("sum(va_cantidad) cantidad, ");
		query.append("sum(venta.va_precio_venta) venta "); 		
		query.append("from clpm_venta venta ");
		query.append("left join clpr_cliente_programa clipro on venta.clpb_cliente_persona=clipro.clpb_cliente_persona ");
		query.append("left join clpb_cliente_persona cliente on clipro.clpb_cliente_persona=cliente.id ");
		query.append("left join clpb_programa programa on clipro.clpb_programa=programa.id ");
		query.append("where 1=1  ");
		query.append("and venta.st_venta='"+CLPConstantes.VENTA_ACTIVA).append("' ");
		query.append("and venta.clpb_cliente_persona is not null  ");
		query.append("group by cliente.id,cliente.de_nombre,cliente.de_ape_paterno,cliente.de_ape_materno, ");
		query.append("cliente.co_code_numero_documento, cliente.de_direccion,cliente.co_telefono_fijo ");
		
		return jdbcTemplate.queryForList(query.toString());
	}
	
	@Transactional(propagation=Propagation.REQUIRES_NEW)
	public List<BNReporteLiquidacion> listReporteLiquidacionConFiltros(ClprPeriodoPrograma periodo, String idPrograma){
		
		
		String fechaInicio = CalendarUtil.calendarToString(CLPConstantes.DATE_PATTERN, periodo.getDaFechaInicioLiq());
		String fechaFin = CalendarUtil.calendarToString(CLPConstantes.DATE_PATTERN,periodo.getDaFechaFinLiq());
		
		StringBuffer query= new StringBuffer();
		query.append("select cliente.id as id, ");
		query.append(" 		(cliente.de_nombre ||' '|| cliente.de_ape_paterno ||' '|| cliente.de_ape_materno) nombre, ");
		query.append("		cliente.co_code_numero_documento documentoIdentidad,cliente.de_direccion direccion, ");
		query.append("		cliente.co_telefono_fijo telefono, ");
		query.append("		sum(venta.va_cantidad) cantidadM3, ");
		query.append("		cliente.da_fecha_nacimiento nacimiento ");
		query.append("	from clpm_venta venta ");
		query.append(" 		join clpr_cliente_programa clipro on venta.clpb_cliente_persona=clipro.clpb_cliente_persona ");
		query.append("		join clpb_cliente_persona cliente on clipro.clpb_cliente_persona=cliente.id ");
		query.append(" 		join clpb_programa programa on clipro.clpb_programa=programa.id ");
		query.append(" 	where  programa.id = ").append(idPrograma);
		query.append(" 		and venta.clpb_cliente_persona is not null ");
		query.append(" 		and trunc(venta.da_fecha_venta) ");
		query.append("					between to_date('").append(fechaInicio).append("','"+CLPConstantes.DATE_PATTERN+"') ");
		query.append(" 					and to_date('").append(fechaFin).append("','"+CLPConstantes.DATE_PATTERN+"') ");
		query.append("		and venta.st_venta = '").append(CLPConstantes.VENTA_ACTIVA).append("' ");
		query.append(" 	group by  cliente.id,cliente.de_nombre,cliente.de_ape_paterno,cliente.de_ape_materno, ");
		query.append(" 		cliente.co_code_numero_documento, cliente.de_direccion,cliente.co_telefono_fijo, cliente.da_fecha_nacimiento ");

		List<BNReporteLiquidacion> listaReporteLiquidacion=findListOfBeans(query.toString(), null, BNReporteLiquidacion.class);
		return listaReporteLiquidacion;
	}
	
	@Transactional(propagation=Propagation.REQUIRES_NEW)
	public List<ClpdMeta> listaMetas(String idPrograma){
		
		StringBuffer query= new StringBuffer();
		query.append("select de_meta as deMeta, ");
		query.append("va_costo as vaCosto, ");
		query.append(" va_meta as VaMeta ");
		query.append(" from clpd_meta ");
		query.append(" where clpb_programa="+new Long(idPrograma)); 
		query.append(" and st_meta='Y' ");
		query.append(" order by vaMeta asc ");
		
		return findListOfBeans(query.toString(),null, ClpdMeta.class);
	}

	public void generarLiquidacion(List<BNReporteLiquidacion> liquidaciones, String idPrograma,String idPeriodo){
		
		ClpbPrograma programa= findClpbPrograma(new Long(idPrograma));
		if(StringUtils.isNotBlank(idPeriodo)){
			ClprPeriodoPrograma periodo= findClprPeriodoPrograma(new Long(idPeriodo));
			
			//Guardar Periodo de Liquidacion		
			ClprPeriodoLiquidacion periodoLiquidacion=guardarPeriodoLiquidacion(programa, periodo);
			
			StringBuffer update = new StringBuffer();
			update.append(" update clpm_historial_liquidacion set st_liquidacion = '").append(CLPConstantes.ST_FALSO).append("' ");
			update.append(" where co_periodo_liquidacion = ").append(periodoLiquidacion.getId());
			jdbcTemplate.update(update.toString());
			
			update = new StringBuffer();
			update.append(" update clpm_liquidacion set st_liquidacion = '").append(CLPConstantes.ST_FALSO).append("' ");
			update.append(" where co_periodo_liquidacion = ").append(periodoLiquidacion.getId());
			jdbcTemplate.update(update.toString());
		
			for (BNReporteLiquidacion liquidacionCliente : liquidaciones) {
			
				ClpmLiquidacion liquiConMetas = new ClpmLiquidacion();
				ClpmHistorialLiquidacion liquiHistorica= new ClpmHistorialLiquidacion();
				
				ClpbClientePersona cliente= findClpbClientePersona(liquidacionCliente.getId());
				
				ClpmLiquidacion clpmLiquidacion=	liquidacionByPeriodoLiquidacionCliente(cliente,periodoLiquidacion);
				if(clpmLiquidacion!=null){
					getHibernateTemplate().delete(clpmLiquidacion);
				}
				
				ClpmHistorialLiquidacion historialLiquidacion=historialLiquidacionByPeriodoLiquidacionCliente(cliente, periodoLiquidacion);
				if(historialLiquidacion!=null){
					getHibernateTemplate().delete(historialLiquidacion);
				}
				
				if (liquidacionCliente.getMeta()!=null){
					//solamente guarda aquellos que alcanzaron las metas
					liquiConMetas.setClpbClientePersona(cliente);
					liquiConMetas.setClprPeriodoLiquidacion(periodoLiquidacion);
					liquiConMetas.setVaMeta(liquidacionCliente.getMeta());
					liquiConMetas.setVaCantidad(liquidacionCliente.getCantidadM3());
					liquiConMetas.setStLiquidacion(true);
					liquiConMetas.setCoUsuarioCreador(getUsuarioLogueado().getUsername());
					liquiConMetas.setDaFechaCreacion(Calendar.getInstance());
					liquiConMetas.setDaFechaModificacion(Calendar.getInstance());
					getHibernateTemplate().save(liquiConMetas);
				}
				
					//En esta tabla se guarda todos los registros de las liquidaciones... es una historica
					liquiHistorica.setClpbClientePersona(cliente);
					liquiHistorica.setClprPeriodoLiquidacion(periodoLiquidacion);
					liquiHistorica.setVaCantidad(liquidacionCliente.getCantidadM3());
					liquiHistorica.setDaFechaCreacion(Calendar.getInstance());
					liquiHistorica.setCoUsuarioCreador(getUsuarioLogueado().getUsername());
					liquiHistorica.setDaFechaModificacion(Calendar.getInstance());
					liquiHistorica.setStLiquidacion(true);
					getHibernateTemplate().save(liquiHistorica);
			}
		}
	}
	

	public Map<String, Object> generarLiquidacionSP(Long idPrograma, Long idPeriodo) {
		
		try {
			
			SimpleJdbcCall spLiquidacion = new SimpleJdbcCall(jdbcTemplate).withProcedureName("SP_LIQUIDACION");
			
			Map<String, Object> parametrosLiquidacionMap = new HashMap<String, Object>();
			parametrosLiquidacionMap.put("p_idPrograma", idPrograma);
			parametrosLiquidacionMap.put("p_idPeriodo", idPeriodo);	
			parametrosLiquidacionMap.put("p_coUsuarioCreador", getUsuarioLogueado().getUsername());	
			
			SqlParameterSource parametrosLiquidacion = new MapSqlParameterSource().addValues(parametrosLiquidacionMap);
			Map<String, Object> parametrosSalida = spLiquidacion.execute(parametrosLiquidacion);
			return parametrosSalida;
			
		} catch (Exception e) {
			System.out.println(e.getMessage());
			
			return null;
		}
		
	}

	private ClprPeriodoLiquidacion guardarPeriodoLiquidacion(ClpbPrograma programa, ClprPeriodoPrograma periodoPrograma){

		List<ClprPeriodoLiquidacion> listaPeriodoLiquidacion= findPeriodoLiquidacionsByProgramaAndPeriodoPrograma(programa,periodoPrograma);
		
		ClprPeriodoLiquidacion periodoLiquidacion= new ClprPeriodoLiquidacion();
	
			
		if(listaPeriodoLiquidacion.isEmpty()){
			periodoLiquidacion.setClpbPrograma(programa);
			periodoLiquidacion.setStEnviado(true);
			periodoLiquidacion.setStPeriodoLiquidacion(true);
			periodoLiquidacion.setDaFechaCreacion(Calendar.getInstance());
			periodoLiquidacion.setDaFechaModificacion(Calendar.getInstance());
			periodoLiquidacion.setDaFechaInicio(periodoPrograma.getDaFechaInicioLiq());
			periodoLiquidacion.setDaFechaFin(periodoPrograma.getDaFechaFinLiq());

			getHibernateTemplate().save(periodoLiquidacion);
		}else{
			periodoLiquidacion= listaPeriodoLiquidacion.get(0);
		}
			
	
		return periodoLiquidacion;
	}
	
	public List<BNPeriodo> periodosPorPrograma(Long idPrograma, Long idPeriodo, boolean itemDefault){
		
		StringBuffer query= new StringBuffer();

		query.append(" select pro.id as id, "); 
		query.append(" (pe.de_periodo ||' ('|| to_char(cast(pro.da_fecha_inicio_liq as date),'"+CLPConstantes.DATE_PATTERN+"') ");
		query.append(" ||' - '|| to_char(cast(pro.da_fecha_fin_liq as date),'"+CLPConstantes.DATE_PATTERN+"') ||') ') as descripcion ");
		query.append(" from clpr_periodo_programa pro ");
		query.append(" join clpb_periodo pe on pro.co_periodo = pe.id ");
		query.append(" where pro.st_periodo_programa='"+CLPConstantes.ST_VERDADERO+"'");
		
		if (idPrograma != null)
		query.append(" and pro.co_programa="+idPrograma);
		
		if (idPeriodo != null)
			query.append(" and pro.id="+idPeriodo);
		
		
		query.append(" ORDER BY pro.da_fecha_inicio_liq DESC ");
		List list = findListOfBeans(query.toString(),null, BNPeriodo.class);
		
		if(itemDefault){
			
			BNPeriodo periodo = new BNPeriodo();
			periodo.setId(new Long(-1));
			periodo.setDescripcion("----");
			
			List listaAuxiliar = new ArrayList<BNPeriodo>();
			listaAuxiliar.add(periodo);
			listaAuxiliar.addAll(list);
			
			list.clear();
			list.addAll(listaAuxiliar);
			
		}
		
		return list;
		
	}
	
	
	public BNResumenLiquidacion generarResumenLiquidacion(BigDecimal coPeriodoLiquidacion){

		StringBuffer query = new StringBuffer();
		query.append("select to_char(sysdate, 'dd/MM/yyyy') as fechaLiquidacion, ");
		query.append("  	p.id as coPrograma, ");
		query.append("   	p.de_programa as dePrograma, ");
		query.append("   	to_char(pl.da_fecha_inicio, 'dd/MM/yyyy') || ' - ' || to_char(pl.da_fecha_fin, 'dd/MM/yyyy') as periodo,");
		query.append("  	count(*) as numeroBeneficiarios,");
		query.append("   	sum(l.va_costo) as totaLiquidacion");
		query.append("	from clpr_periodo_liquidacion pl join clpm_liquidacion l ");
		query.append("  					on pl.id = l.co_periodo_liquidacion ");
		query.append("      join clpb_programa p on pl.co_programa = p.id ");
		query.append("	where pl.id = ").append(coPeriodoLiquidacion);
		query.append("	group by p.id, p.de_programa, pl.da_fecha_inicio, pl.da_fecha_fin ");
		
		List<BNResumenLiquidacion> list = findListOfBeans(query.toString(), null, BNResumenLiquidacion.class);
		if(!list.isEmpty()){
			BNResumenLiquidacion resumenLiquidacion = list.get(0);
			
			query = new StringBuffer();
			query.append(" select va_costo from clpd_meta where clpb_programa = ").append(resumenLiquidacion.getCoPrograma()); 
			List listaMeta = findListOfArrays(query.toString(), null);
			if(!listaMeta.isEmpty()){
				
				Object [] array = (Object[]) listaMeta.get(0);
				resumenLiquidacion.setRentaBasica(new Double(array[0].toString()));
			}
			
			return resumenLiquidacion;
		}
		return null;	  
	}
	
	public ClprPeriodoPrograma findClprPeriodoPrograma(Long id){
		return getHibernateTemplate().get(ClprPeriodoPrograma.class, id);
	}

	public ClpbClientePersona findClpbClientePersona(Long id){
		
		return getHibernateTemplate().get(ClpbClientePersona.class, id);
	}
	
	
	public ClpbPrograma findClpbPrograma(Long id){
		
		return getHibernateTemplate().get(ClpbPrograma.class, id);
	}
	
	public List<ClprPeriodoLiquidacion> findPeriodoLiquidacionsByProgramaAndPeriodoPrograma(ClpbPrograma programa, ClprPeriodoPrograma periodoPrograma){
	
		Criteria criteria = DetachedCriteria.forClass(ClprPeriodoLiquidacion.class)
		.getExecutableCriteria(getSessionFactory().getCurrentSession());

		criteria.add(Restrictions.eq("clpbPrograma.id", programa.getId()));
		
		criteria.add(Restrictions.eq("daFechaInicio", periodoPrograma.getDaFechaInicioLiq()));
		
		criteria.add(Restrictions.eq("daFechaFin", periodoPrograma.getDaFechaFinLiq()));
		
		criteria.addOrder(Order.desc("id"));
		
		List<ClprPeriodoLiquidacion> lista = criteria.list(); 
		return lista;
		
	}
	
	public List<ClpmLiquidacion> findLiquidacionByPeriodoLiquidacionAndCliente(ClpbClientePersona cliente,ClprPeriodoLiquidacion periodoLiquidacion){
		
		Criteria criteria = DetachedCriteria.forClass(ClpmLiquidacion.class)
		.getExecutableCriteria(getSessionFactory().getCurrentSession());

		criteria.add(Restrictions.eq("clpbClientePersona", cliente));
		criteria.add(Restrictions.eq("clprPeriodoLiquidacion", periodoLiquidacion));
		criteria.addOrder(Order.desc("id"));
		
		List<ClpmLiquidacion> lista = criteria.list(); 
		return lista;
	}

	public ClpmLiquidacion liquidacionByPeriodoLiquidacionCliente(ClpbClientePersona cliente,ClprPeriodoLiquidacion periodoLiquidacion){
		
		Criteria criteria = DetachedCriteria.forClass(ClpmLiquidacion.class)
		.getExecutableCriteria(getSessionFactory().getCurrentSession());

		criteria.add(Restrictions.eq("clpbClientePersona", cliente));
		criteria.add(Restrictions.eq("clprPeriodoLiquidacion", periodoLiquidacion));
		criteria.addOrder(Order.desc("id"));
		return (ClpmLiquidacion) criteria.uniqueResult();
	}

	public List<ClpmHistorialLiquidacion> findHistorialLiquidacionByPeriodoLiquidacionAndCliente(ClpbClientePersona cliente,ClprPeriodoLiquidacion periodoLiquidacion){

		Criteria criteria = DetachedCriteria.forClass(ClpmHistorialLiquidacion.class)
		.getExecutableCriteria(getSessionFactory().getCurrentSession());

		criteria.add(Restrictions.eq("clpbClientePersona", cliente));
		
		criteria.add(Restrictions.eq("clprPeriodoLiquidacion", periodoLiquidacion));
		
		criteria.addOrder(Order.desc("id"));
		
		List<ClpmHistorialLiquidacion> lista = criteria.list(); 
		return lista;

	}
	
	public ClpmHistorialLiquidacion historialLiquidacionByPeriodoLiquidacionCliente(ClpbClientePersona cliente,ClprPeriodoLiquidacion periodoLiquidacion){

		Criteria criteria = DetachedCriteria.forClass(ClpmHistorialLiquidacion.class)
		.getExecutableCriteria(getSessionFactory().getCurrentSession());

		criteria.add(Restrictions.eq("clpbClientePersona", cliente));
		criteria.add(Restrictions.eq("clprPeriodoLiquidacion", periodoLiquidacion));
		criteria.addOrder(Order.desc("id"));
		List<ClpmHistorialLiquidacion>  listaHistorial= criteria.list();
		
		ClpmHistorialLiquidacion historiaLiquidacion= new ClpmHistorialLiquidacion();

		if (!listaHistorial.isEmpty())
			historiaLiquidacion= listaHistorial.get(0);
		
		return historiaLiquidacion;

	}
	
	public List<BNReporteLiquidacion> consultarLiquidaciones(ClpbPrograma idPrograma, ClprPeriodoPrograma idPeriodo){

		StringBuffer query= new StringBuffer();
		List<ClprPeriodoLiquidacion> listaPeriodoLiquidacion= findPeriodoLiquidacionsByProgramaAndPeriodoPrograma(idPrograma,idPeriodo);
		
		if(!listaPeriodoLiquidacion.isEmpty()){
			query.append(" select cliente.id as id,  (cliente.de_nombre ||' '|| cliente.de_ape_paterno ||' '|| cliente.de_ape_materno) as nombre, ");
			query.append(" cliente.co_code_numero_documento as documentoIdentidad,cliente.de_direccion as direccion, cliente.co_telefono_fijo as telefono, ");
			query.append(" cliente.da_fecha_nacimiento as nacimiento, va_cantidad as cantidadM3, va_meta as meta ");
			query.append(" from clpm_liquidacion liqui ");
			query.append(" left join clpb_cliente_persona cliente on liqui.co_cliente_persona=cliente.id ");
			query.append(" where st_liquidacion='"+CLPConstantes.ST_VERDADERO+"' ");
			query.append(" and co_periodo_liquidacion="+listaPeriodoLiquidacion.get(0).getId());
		}
		
		System.out.println(query.toString());
		
		return findListOfBeans(query.toString(), null, BNReporteLiquidacion.class);
	}

	public List<ClpbPrograma> listadoProgramasHistoricos(){

		StringBuffer query= new StringBuffer();
		query.append(" select DISTINCT(periodo.co_programa), programa.id as id  ");
		query.append(" from clpb_programa programa ");
		query.append(" left join clpr_periodo_programa periodo on periodo.co_programa= programa.id ");

		List<Map<String, Object>> listado=jdbcTemplate.queryForList(query.toString());
		
		List<ClpbPrograma> programas= new ArrayList<ClpbPrograma>();
		for (Iterator it = listado.iterator(); it.hasNext();) {
			LinkedHashMap object = (LinkedHashMap) it.next();
			String idPrograma= String.valueOf(object.get("id"));
			if(StringUtils.isNotBlank(idPrograma)){
				ClpbPrograma programa= getHibernateTemplate().get(ClpbPrograma.class,new Long(idPrograma));
				programas.add(programa);
			}
		}
		return programas;
	}
	
	public List<BNPeriodo> periodosPorProgramaHistorio(Long idPrograma){
		
		StringBuffer query= new StringBuffer();
		query.append(" select pro.id as id, "); 
		query.append(" (pe.de_periodo ||' ('|| to_char(cast(pro.da_fecha_inicio_liq as date),'"+CLPConstantes.DATE_PATTERN+"') ");
		query.append(" ||' - '|| to_char(cast(pro.da_fecha_fin_liq as date),'"+CLPConstantes.DATE_PATTERN+"') ||') ') as descripcion ");
		query.append(" from clpr_periodo_programa pro ");
		query.append(" join clpb_periodo pe on pro.co_periodo = pe.id ");
		query.append(" and pro.co_programa="+idPrograma);
		
		return findListOfBeans(query.toString(),null, BNPeriodo.class);
	}
	
	/**
	 * 
	 * @param coPrograma: codigo del programa a buscar
	 * @param coPeriodoPrograma: codigo del periodo del programa que se debe buscar en las liquidaciones
	 * @return lista de personas que estan incluidas en la liquidacion del periodo elegido
	 */
	public List<Map<String, Object>> obtenerRegistrosLiquidacionPorPeriodo(BigDecimal coPrograma, BigDecimal coPeriodoPrograma){
		
		StringBuffer query = new StringBuffer();
		query.append("select cp.id as id, ");
//		query.append("		'' as poliza, ");
		query.append("		tdp.co_codigo_seguro as tipoDocumento, ");
		query.append("		cp.co_code_numero_documento as numeroDocumento, ");
		query.append("		cp.de_ape_paterno as apellidoPaterno, ");
		query.append("		cp.de_ape_materno as apellidoMaterno, ");
		query.append("		cp.de_nombre as nombre, ");
		query.append("		to_char(cp.da_fecha_nacimiento,'yyyyMMdd') as fechaNacimiento,");
		query.append("		case");
		query.append("    		when cp.de_sexo = '01' then 'M'");
		query.append("    		when cp.de_sexo = '02' then 'F'");
		query.append("		end as sexo, ");
//		query.append("		'' as inicioVigencia, ");
//		query.append("		'' as finVigencia, ");
		query.append("		m.va_costo as prima, ");
		query.append("		e.id as estacion ");
		query.append("	from clpm_liquidacion l join clpb_cliente_persona cp on l.co_cliente_persona = cp.id ");
		query.append("		join clpb_tipo_documento_persona tdp on cp.co_tipo_documento = tdp.id");
		query.append("		join clpb_tarjeta_persona tp on cp.id = tp.co_cliente_persona ");
		query.append("		join clpb_estacion e on tp.co_estacion = e.id ");
		query.append("		join clpr_periodo_liquidacion pl on l.co_periodo_liquidacion = pl.id ");
		query.append("		join clpb_programa p on pl.co_programa = p.id");
		query.append("		join clpd_meta m on p.id = m.clpb_programa and l.va_meta = m.va_meta ");
		query.append("		join clpr_periodo_programa pp on to_char(pl.da_fecha_inicio, 'dd/MM/yyyy') = to_char(pp.da_fecha_inicio_liq , 'dd/MM/yyyy')"); 
		query.append("			and to_char(pl.da_fecha_fin, 'dd/MM/yyyy') = to_char(pp.da_fecha_fin_liq , 'dd/MM/yyyy') ");
		query.append("	where p.id = ").append(coPrograma);
		query.append("		and pp.id = ").append(coPeriodoPrograma);
		query.append("		and l.st_liquidacion = '").append(CLPConstantes.ST_VERDADERO).append("' ");
		query.append("		and cp.st_cliente_persona = '").append(CLPConstantes.ST_VERDADERO).append("'  ");
		query.append("		and tp.st_tarjeta_persona = '").append(CLPConstantes.ST_VERDADERO).append("'"); 
		query.append("		and e.st_estacion  = '").append(CLPConstantes.ST_VERDADERO).append("'");
		query.append("		and pl.st_periodo_liquidacion = '").append(CLPConstantes.ST_VERDADERO).append("'  ");
		query.append("		and p.st_programa = '").append(CLPConstantes.ST_VERDADERO).append("' ");
		query.append("		and m.st_meta = '").append(CLPConstantes.ST_VERDADERO).append("' ");
		query.append("		and pp.st_periodo_programa = '").append(CLPConstantes.ST_VERDADERO).append("' ");
		query.append("	order by cp.co_code_numero_documento asc ");
		
		List list = findListOfMaps(query.toString(), null);
		return list;
	}
	
	public List<BNPeriodo> periodosPorHistorioLiquidacion(Long idPrograma){
		
		StringBuffer query= new StringBuffer();	
		query.append("select distinct pp.id as id, ");
		query.append("		pe.de_periodo || ' (' || to_char(pl.da_fecha_inicio, 'dd/MM/yyyy') || ' - (' || to_char(pl.da_fecha_fin, 'dd/MM/yyyy') || ')'  as descripcion ");
		query.append("	from clpr_periodo_liquidacion pl join clpm_liquidacion l on pl.id = l.co_periodo_liquidacion ");
		query.append("		join clpb_programa p on pl.co_programa = p.id ");
		query.append("		join clpr_periodo_programa pp on to_char(pl.da_fecha_inicio, 'dd/MM/yyyy') = to_char(pp.da_fecha_inicio_liq , 'dd/MM/yyyy')");
		query.append("  		and to_char(pl.da_fecha_fin, 'dd/MM/yyyy') = to_char(pp.da_fecha_fin_liq , 'dd/MM/yyyy') ");
		query.append("		join clpb_periodo pe on pp.co_periodo = pe.id  ");
		query.append("	where p.id =  ").append(idPrograma);
		query.append("		and pl.st_periodo_liquidacion = '").append(CLPConstantes.ST_VERDADERO).append("'  ");
		query.append("		and l.st_liquidacion = '").append(CLPConstantes.ST_VERDADERO).append("' ");
		query.append("		and p.st_programa = '").append(CLPConstantes.ST_VERDADERO).append("' ");
		query.append("		and pp.st_periodo_programa = '").append(CLPConstantes.ST_VERDADERO).append("' ");
		query.append("	order by pp.id desc  ");
		
		List list = findListOfBeans(query.toString(),null, BNPeriodo.class);
		return list;
	}

	public int verificarExistePeriodoLiq(Long idPrograma, Long idPeriodo) {

		StringBuffer query = new StringBuffer();
		query.append(" select ");
		query.append(" count(pl.id) ");
		query.append(" from clpr_periodo_liquidacion pl ");
		query.append(" join clpr_periodo_programa pro ");
		query.append(" on  to_char(pl.da_fecha_inicio,'"+CLPConstantes.DATE_PATTERN+"') = to_char(pro.da_fecha_inicio_liq,'"+CLPConstantes.DATE_PATTERN+"') ");
		query.append(" and to_char(pl.da_fecha_fin,'"+CLPConstantes.DATE_PATTERN+"') = to_char(pro.da_fecha_fin_liq,'"+CLPConstantes.DATE_PATTERN+"') ");
		query.append(" where 1 = 1 ");
		query.append(" and pl.co_programa = ").append(idPrograma);
		query.append(" and pro.id = ").append(idPeriodo);
		query.append(" and pl.st_periodo_liquidacion = '").append(CLPConstantes.ST_VERDADERO).append("'");
		
		System.out.println("* verificarExistePeriodoLiq: "+query.toString());
		return jdbcTemplate.queryForInt(query.toString());
	}
}
